package com.study.meng.bigevent.common.handler;

import com.study.meng.bigevent.entity.Result;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.stream.Collectors;

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理参数校验失败的异常
     * 当Controller中使用@Valid或@Validated注解的参数校验失败时触发
     *
     * @param ex 参数校验异常对象，包含校验失败的详细信息
     * @return 统一返回结果，包含：
     * - 状态码400表示客户端请求参数错误
     * - 错误信息为所有校验失败字段的错误消息拼接而成
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidationExceptions(MethodArgumentNotValidException ex) {
        // 从异常中获取所有字段校验错误
        String errorMsg = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                // 提取每个字段的错误消息
                .map(FieldError::getDefaultMessage)
                // 用逗号连接所有错误消息
                .collect(Collectors.joining(", "));
        // 返回400状态码和组合后的错误信息
        return Result.error(400, errorMsg);
    }

    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public Result handleSqlIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException ex) {
        String errorMsg = "数据操作失败";

        // 根据具体错误信息返回更友好的提示
        if (ex.getMessage().contains("Duplicate entry")) {
            errorMsg = "数据已存在";
        } else if (ex.getMessage().contains("cannot be null")) {
            errorMsg = "必填字段不能为空";
        }

        return Result.error(409, errorMsg);
    }
}